import {downIconSvgStr} from './dragSvg';
import {getValByDom, getScrollVal, positionFromBody, getChildrenNode} from './dragUtils';

let container;
let editorRef;

// 拖拽过程中样式
const dragStyle = {
  background: 'rgba(247,248,250,0.95)',
  opacity: 1,
  border: '1px solid #E8E9EB',
  borderRadius: '3px',
  overflow: 'hidden',
};
const iconBox = document.createElement('div');
const tipDOM = document.createElement('div');

iconBox.setAttribute('data-drag-type', 'icon');
iconBox.setAttribute('contenteditable', "false");
iconBox.innerHTML = `<div class="mp-drag-icon-svg-box">${downIconSvgStr}</div>`;
iconBox.className = 'mp-drag-icon';
iconBox.appendChild(tipDOM);

const blueLine = document.createElement('div');
blueLine.style.background = '#5A90FA';
blueLine.style.height = '1px';
// 防止元素抖动
blueLine.style.marginTop = '-1px';
let scrollTimeIntervalId;

const iconMouseDown = (event) => {
  event.preventDefault();
  // button: 0 => 鼠标左键 | 2 => 鼠标右键 | 1 => 鼠标滚轮
  dragObj.mouseDownButton = event.button;
  if (dragObj.mouseDownButton !== 0) {
    return;
  }
  dragObj.mouseIsDown = true;
  dragObj.startDom = dragObj.hoverDom;
};

function resetState() {
  clearInterval(scrollTimeIntervalId);
  scrollTimeIntervalId = 0;
  Object.assign(dragObj, {
    copyDom: null,
    startDom: null,
    isDragging: false,
    startPoint: {
      x: null,
      y: null,
    },
    mouseIsDown: false,
    menuList: [],
    editorProps: null,
  });
}

function isOutHtml(mousePoint) {
  const containerStyle = window.getComputedStyle(container, null);
  const startPoint = positionFromBody(container);
  const containerPoint = {
    startPoint,
    endPoint: {
      x: startPoint.x + (+parseFloat(containerStyle.width) || 0),
      y: startPoint.y + (+parseFloat(containerStyle.height) || 0),
    },
  };
  const htmlScrollTop = document.querySelector('html').scrollTop > 0 ? document.querySelector('html').scrollTop : 0;
  const windowPoint = {
    startPoint: {
      y: htmlScrollTop,
    },
    endPoint: {
      y: window.innerHeight + htmlScrollTop,
    },
  };

  if (mousePoint.y <= htmlScrollTop && windowPoint.startPoint.y > 0) {
    clearInterval(scrollTimeIntervalId);
    scrollTimeIntervalId = setInterval(() => {
      if (document.querySelector('html').scrollTop > 0) {
        document.querySelector('html').scrollTop--;
      }
      else {
        document.querySelector('html').scrollTop = 0;
      }
    }, 20);
  }
  else if (
    mousePoint.y >= windowPoint.endPoint.y
    && containerPoint.endPoint.y < document.querySelector('html').scrollHeight
  ) {
    clearInterval(scrollTimeIntervalId);
    scrollTimeIntervalId = setInterval(() => {
      if (
        document.querySelector('html').scrollTop
        < document.querySelector('html').scrollHeight - window.innerHeight
      ) {
        document.querySelector('html').scrollTop++;
      }
      else {
        document.querySelector('html').scrollTop
          = document.querySelector('html').scrollHeight - window.innerHeight;
      }
    }, 20);
  }
  else {
    clearInterval(scrollTimeIntervalId);
    scrollTimeIntervalId = 0;
  }
}

function documentMove(event) {
  const {scrollTop, scrollLeft} = getScrollVal();
  if (dragObj.copyDom) {
    Object.assign(dragObj.copyDom.style, {
      left: `${event.pageX + 10 - scrollLeft}px`,
      top: `${event.pageY - 12 - scrollTop}px`,
    });
  }
  isOutHtml({
    x: event.pageX,
    y: event.pageY,
  });
}

const iconMouseMove = (event) => {
  createDomToBody(event);
}

// 拖动过程中编辑器内元素禁用所有事件
function editorNodePreventDefault() {
  const sonNodes = getChildrenNode(container);
  const allChildrenNodes = sonNodes.reduce((rel, ele) => {
    if (ele.dataset.dragType !== 'icon') {
      rel.push(...getChildrenNode(ele));
    }
    return rel;
  }, []);
  allChildrenNodes.forEach((ele) => {
    if (ele.parentNode !== container && !ele.className.includes('mp-editor-container-drag-hover-disabled')) {
      ele.className += ' mp-editor-container-drag-hover-disabled';
    }
  });
}

function documentMouseUp() {
  if (dragObj.copyDom) {
    dragObj.copyDom.remove();
  }
  Object.assign(document.querySelector('html').style, {
    userSelect: 'initial',
    cursor: 'initial',
  });
  blueLine.remove();
  const editor = editorRef;
  const targetDom = dragObj.targetDom;
  const hoverDom = dragObj.hoverDom;

  const targetIndex = Array.prototype.indexOf.call(targetDom.parentNode.children, targetDom);
  const sourceIndex = Array.prototype.indexOf.call(hoverDom.parentNode.children, hoverDom) + 1;
  dragObj.copyDom = null;
  dragObj.isDragging = false;
  editor.moveTo(targetIndex, sourceIndex);
  // const sourceNodeKey = getValByDom(dragObj.startDom, 'key');
  // const targetNodeKey = getValByDom(dragObj.hoverDom, 'key');
  // const insertIndex = getEditorNodeIndex(targetNodeKey);
  // resetCheckedClassName();
  // if (sourceNodeKey && targetNodeKey) {
  //   editor.moveNodeByKey(sourceNodeKey, editor.value.document.key, insertIndex);
  // }
  // blueLine.remove();
  document.removeEventListener('mousemove', documentMove);
  document.removeEventListener('mouseup', documentMouseUp);
  resetState();
}

function createDomToBody(event) {
  // button: 0 => 鼠标左键 | 2 => 鼠标右键 | 1 => 鼠标滚轮
  if (dragObj.mouseDownButton !== 0 || !dragObj.mouseIsDown) {
    return;
  }
  if (dragObj.copyDom) {
    dragObj.copyDom.remove();
  }
  const domNode = dragObj.hoverDom;
  const computedStyle = window.getComputedStyle(domNode, null);
  const {width, height, fontSize, lineHeight} = computedStyle;
  const pointFromBody = positionFromBody(dragObj.hoverDom);
  const {scrollTop, scrollLeft} = getScrollVal();

  document.addEventListener('mousemove', documentMove);
  document.addEventListener('mouseup', documentMouseUp);

  dragObj.copyDom = domNode.cloneNode(true);
  dragObj.targetDom = domNode;
  Object.assign(dragObj.copyDom.style, {
    width,
    height,
    fontSize,
    lineHeight,
    position: 'fixed',
    left: `${pointFromBody.x - scrollLeft + 20 - 32}px`,
    top: `${pointFromBody.y - scrollTop}px`,
    ...dragStyle,
  });
  document.body.appendChild(dragObj.copyDom);
  Object.assign(document.querySelector('html').style, {
    userSelect: 'none',
    cursor: 'pointer',
  });
  dragObj.isDragging = true;
}

// iconBox.addEventListener('mouseover', iconMouseOver);
iconBox.addEventListener('mousedown', iconMouseDown);
iconBox.addEventListener('mousemove', iconMouseMove);
iconBox.addEventListener('mouseup', () => {
  console.log('mouseup');
});
const dragObj = {
  copyDom: null,
  hoverDom: null,
  startDom: null,
  isDragging: false,
  startPoint: {
    x: null,
    y: null,
  },
  menuList: [],
  mouseDownButton: 0,
  mouseIsDown: false,
  editorProps: null,
};

// 获取编辑器的子元素
function getEditorChild(node) {
  if (node && node.parentNode === container) {
    return node;
  }

  if (node) {
    return getEditorChild(node.parentNode);
  }

  return null;
}

function getPositionFromParent(ele) {
  return {
    x: ele.offsetLeft,
    y: ele.offsetTop,
  };
}

// 判断坐标是在拖拽开始的上方还是下方输入 'up', 'down', 'self'
function moveDirection(point) {
  if (point.y > dragObj.startPoint.y) {
    return 'down';
  }
  else if (point.y === dragObj.startPoint.y) {
    return 'self';
  }
  return 'up';

}

function insertBlueLine(blockModule, point) {
  const direction = moveDirection(point);
  if (!blockModule) {
    return;
  }
  if (!blockModule.nextSibling) {
    container.appendChild(blueLine);
    return;
  }
  if (['down', 'self'].includes(direction)) {
    container.insertBefore(blueLine, blockModule.nextSibling);
  }
  else {
    container.insertBefore(blueLine, blockModule);
  }
}

const onHoverDom = (event) => {
  event.preventDefault();
  const blockModule = getEditorChild(event.target);

  if (!blockModule || blockModule.dataset.dragType === 'icon') {
    return;
  }

  // 这里后期优化，getComputedTop应该是来自于各个root元素的计算位置。
  // let computedTop = getComputedTop(slateType, blockModule);

  const iconPoint = getPositionFromParent(blockModule);

  if (blockModule) {
    dragObj.hoverDom = blockModule;
  }

  if (dragObj.isDragging) {
    insertBlueLine(blockModule, iconPoint);
    return;
  }

  Object.assign(iconBox.style, {
    left: `${iconPoint.x - 32}px`,
    // top: `${iconPoint.y + computedTop}px`,
    top: `${iconPoint.y}px`,
  });

  container.appendChild(iconBox);

  // // 鼠标悬停事件
  // if (event.target.dataset.slateNode === "element") {
  //   document.querySelector('.mp-drag-icon').style.top = `${event.target.offsetTop}px`
  // }
};

export function bindDragEventToDom(ele, ref, editorProps) {
  container = ele;
  editorRef = ref;
  dragObj.editorProps = editorProps;
  container.addEventListener('mouseover', onHoverDom);
  // container.addEventListener('mouseleave', () => {
  //   // 鼠标离开事件
  //   console.log(2)
  // });
  // container.addEventListener('mousemove', () => {
  //   // 鼠标移动事件
  //   console.log(3)
  // });
  // initMenu(editorRef.current, iconBox, dragObj, delIcon);
}

export function removeDragEventFromDom(ele, ref) {
  container = ele;
  editorRef = ref;
  container.removeEventListener('mouseleave', onHoverDom);
  // container.removeEventListener('mouseleave', leaveContainer);
  // container.removeEventListener('mousemove', moveOnContainer);
  // uninstallMenu();
}
